package com.heatup.apt.api.service.impl;

import com.heatup.apt.api.service.CoachService;
import com.heatup.apt.api.service.DataDictService;
import com.heatup.apt.api.service.OrderVoucherService;
import com.heatup.apt.api.service.PrivateCoachOpenOrderService;
import com.heatup.apt.common.constants.ErrorCodeConstants;
import com.heatup.apt.common.constants.OrderContants;
import com.heatup.apt.common.dao.*;
import com.heatup.apt.common.dao.store.StoreCoachMapper;
import com.heatup.apt.common.dao.user.UserInfoMapper;
import com.heatup.apt.common.util.DateUtils;
import com.heatup.apt.common.util.OrderUtil;
import com.heatup.apt.common.util.QRCodeUtil;
import com.heatup.apt.common.util.StringUtil;
import com.heatup.apt.model.DataDict;
import com.heatup.apt.model.api.ApiResultModel;
import com.heatup.apt.model.coach.CoachBriefResultModel;
import com.heatup.apt.model.coach.CoachCourseInfo;
import com.heatup.apt.model.coach.CoachInfo;
import com.heatup.apt.model.coach.CoachStoreInfo;
import com.heatup.apt.model.course.*;
import com.heatup.apt.model.management.CoachInf;
import com.heatup.apt.model.order.OrderCourseCoach;
import com.heatup.apt.model.order.OrderDetail;
import com.heatup.apt.model.order.OrderInfo;
import com.heatup.apt.model.order.PresalePrivateCourseOrderModel;
import com.heatup.apt.model.product.ServicePrice;
import com.heatup.apt.model.store.StoreCoach;
import com.heatup.apt.model.user.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 *@Author: timo
 *@Date: 2018/3/26 11:02
 *@Description:
 * 创建私教课程订单
 *
 */
@Service
public class PrivateCoachOpenOrderServicelmpl implements PrivateCoachOpenOrderService {

    Logger logger = LoggerFactory.getLogger(PrivateCoachOpenOrderServicelmpl.class);

    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private OrderDetailMapper orderDetailMapper;
    @Resource
    private CoachService coachService;
    @Resource
    private OrderVoucherService orderVoucherService;
    @Resource
    private OrderCourseCoachMapper orderCourseCoachMapper;
    @Resource
    private CourseSignMapper courseSignMapper;
    @Resource
    private CourseInfoMapper courseInfoMapper;
    @Resource
    private ServicePriceMapper servicePriceMapper;
    @Resource
    private CourseCoachMapper courseCoachMapper;
    @Resource
    private CourseScheduleMapper courseScheduleMapper;
    @Resource
    private DataDictService dataDictService;
    @Resource
    private StoreCoachMapper storeCoachMapper;
    @Resource
    private CourseStoreMapper courseStoreMapper;
    @Resource
    private UserInfoMapper userInfoMapper;

    @Override
    public ApiResultModel createPrepayPrivateCourseOrder(PresalePrivateCourseOrderModel orderModel, UserInfo userInfo) {
        ApiResultModel<Object> resultModel = new ApiResultModel<>();

        // step 1 check create order param is it correct
        CoachInfo coachInfo = coachService.queryCoachByMobile(userInfo.getMobile());

        resultModel = checkParam(orderModel, userInfo, coachInfo);
        if (resultModel.getRet() == ApiResultModel.RET_ERROR) return resultModel;

        // step 2 create order
        OrderInfo orderInfo = createOrderInfo(orderModel, userInfo, coachInfo);


        Map<String,Object> reslutMap = new HashMap<>();
        reslutMap.put("orderInfo",orderInfo);
        resultModel.setRet(resultModel.RET_SUCCESS);
        resultModel.setMsg("订单创建成功！");
        resultModel.setData(reslutMap);
        return resultModel;
    }

    /**
     *@Author: timo
     *@Date: 2018/3/26 14:22
     *@Description:
     * 创建支付二维码
     *
     */
    @Override
    public ApiResultModel queryPayPrivateCourseOrderDetail(Integer orderId, Integer isCoach, UserInfo userInfo) {
        ApiResultModel<Object> resultModel = new ApiResultModel<>();
        PresalePrivateCourseOrderModel orderModel = orderInfoMapper.queryPtOpenBillingDetailByOrderIdAndUserId(orderId,0);
        orderModel.setPayTypeName(OrderContants.PayType.getPayType(orderModel.getPayType()).getName());

        // 教练查看订单的时候就需要  创建支付二维码 是教练的时候就创建支付二维码
        if (isCoach == 1){
            List<DataDict> dataDictList = dataDictService.queryDataDicts("COACH_OPEN_BILLING_USER_PAY_URL");
            String payUrl = "";
            if(dataDictList.size() > 0){
                payUrl = dataDictList.get(0).getDictCode();
            }
            payUrl = payUrl+"?orderId="+orderModel.getOrderId()+"&type="+orderModel.getPayType();
            logger.info("payUrl:"+payUrl);
            payUrl = "data:image/gif;base64,"+QRCodeUtil.createQRCodeToBAS64String(payUrl,200,200);
            orderModel.setPayQRCode(payUrl);
        }else{
            // 用户查看订单详情 这里就需要判断用户是否关注
            orderModel.setUserNickName(userInfo.getNickName());
            orderModel.setUserMobile(userInfo.getMobile());
            orderModel.setSubscribe(userInfo.getSubscribe());
        }
        resultModel.setRet(resultModel.RET_SUCCESS);
        resultModel.setData(orderModel);
        return resultModel;
    }

    /**
     *@Author: timo
     *@Date: 2018/3/27 00:19
     *@Description:
     * 私教教练开单 -- > 用户支付完成订单之后 需要创建私教课程
     * 步骤如下：
     * 1.创建私教课程（course_info）
     * 2.创建课程教练表的数据 (course_coach)
     * 3.创建课程服务价格 (Service_price)
     * 4.更新教练日程表（course_sign）
     * 5.更细订单课程教练表（order_course_coach）
     *
     */
    @Override
    public boolean createPrivateCourse(OrderInfo orderInfo, OrderDetail orderDetail) {
        return createCourse(orderInfo, orderDetail);
    }



    /**
     *@Author: timo
     *@Date: 2018/3/26 16:34
     *@Description:
     * 校验预支付私教订单的参数
     *
     */
    public ApiResultModel checkParam(PresalePrivateCourseOrderModel orderModel, UserInfo userInfo, CoachInfo coachInfo){
        ApiResultModel<Object> resultModel = new ApiResultModel<>();
        resultModel.setRet(resultModel.RET_ERROR);

        // 未登录
        if(userInfo == null){
            resultModel.setRet(resultModel.RET_ERROR);
            resultModel.setErrorCode(ErrorCodeConstants.Code.USER_NOT_LOGIN.getCode());
            resultModel.setMsg(ErrorCodeConstants.Code.USER_NOT_LOGIN.getMessage());
            return resultModel;
        }

        // 没有绑定手机号码不是教练
        if(StringUtil.isEmpty(userInfo.getMobile())){
            resultModel.setRet(resultModel.RET_ERROR);
            resultModel.setErrorCode(ErrorCodeConstants.Code.COACH_MOBILE_NOT_BIND.getCode());
            resultModel.setMsg(ErrorCodeConstants.Code.COACH_MOBILE_NOT_BIND.getMessage());
            return resultModel;
        }

        // 查询教练


        // 判断该手机号码是否绑定教练了
        if(coachInfo == null){
            resultModel.setRet(resultModel.RET_ERROR);
            resultModel.setErrorCode(ErrorCodeConstants.Code.COACH_NOT_MATCH.getCode());
            resultModel.setMsg(ErrorCodeConstants.Code.COACH_NOT_MATCH.getMessage());
            return resultModel;
        }

        // 判断该教练是否在职
        if(!"1".equals(coachInfo.getStatus())){
            resultModel.setRet(resultModel.RET_ERROR);
            resultModel.setErrorCode(ErrorCodeConstants.Code.COACH_NOT_MATCH.getCode());
            resultModel.setMsg(ErrorCodeConstants.Code.COACH_NOT_MATCH.getMessage());
            return resultModel;
        }

        // 只有是私教教练才能开单
        if(coachInfo.getIsPrivate() != 1){
            resultModel.setRet(resultModel.RET_ERROR);
            resultModel.setMsg("温馨提示：您没有开私教订单的权限");
            return resultModel;
        }
        resultModel.setRet(resultModel.RET_SUCCESS);
        return resultModel;
    }

    /**
     *@Author: timo
     *@Date: 2018/3/26 14:11
     *@Description:
     * 创建订单
     *
     */
    public OrderInfo createOrderInfo(PresalePrivateCourseOrderModel orderModel, UserInfo userInfo, CoachInfo coachInfo){
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setAmount(orderModel.getPayAmount());
        orderInfo.setOrderStatus(OrderContants.OrderStatus.NORMAL.getStatus());
        orderInfo.setCancelAble("1");
        orderInfo.setUserId(0);
        orderInfo.setServiceId(0);
        orderInfo.setCancelBackmoney(1);
        orderInfo.setPayType(orderModel.getPayType());
        orderInfo.setPayStatus(OrderContants.PayStatus.UNPAID);
        orderInfo.setCreatedTime(new Date());
        orderInfo.setOrderSource(orderModel.getPayType() == 1 ? OrderContants.ORDER_SOURCE_WECHAT : OrderContants.ORDER_SOURCE_POS);
        orderInfo.setOrderType(OrderContants.OrderType.pt.getIndex());
        orderInfo.setOrderNumber(OrderUtil.getOrderNumber(orderInfo.getOrderSource()+""));
        orderInfo.setCancel(0);
        orderInfo.setPrimePrice(orderModel.getPayAmount());
        orderInfo.setPriceTypeCode("1");
        orderInfo.setWeixinAmt(BigDecimal.ZERO);
        orderInfo.setConsumeAmt(BigDecimal.ZERO);
        orderInfo.setCompanyAmt(BigDecimal.ZERO);
        orderInfo.setTradeId(getTradeId());
        int addOrderCount = orderInfoMapper.insertSelective(orderInfo);
        if(addOrderCount > 0){

            // step 1 create order detail
            Integer storeId = storeCoachMapper.queryStoreIdByCoachId(coachInfo.getId());
            OrderDetail orderDetail = cerateOrderDetail(orderModel,userInfo,orderInfo, storeId);

            // step 2 create order course coach data
            createOrderCourseCoach(orderModel,userInfo,orderInfo);

            // step 3 crate order bill
            orderVoucherService.createOrderVoucher(orderModel.getBillImg(),"bill",orderInfo.getId(),userInfo.getId(),orderModel.getRemark(),userInfo.getId());

            // step 4 cerate order contract
            orderVoucherService.createOrderVoucher(orderModel.getContractImg(),"contract",orderInfo.getId(),userInfo.getId(),orderModel.getRemark(),userInfo.getId());
        }else{
            throw new RuntimeException("insert order data is error");
        }
        return orderInfo;
    }

    /**
     *@Author: timo
     *@Date: 2018/3/26 14:11
     *@Description:
     * 创建订单详情
     *
     */
    public OrderDetail cerateOrderDetail(PresalePrivateCourseOrderModel orderModel, UserInfo userInfo, OrderInfo orderInfo, Integer storeId){
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderInfo.getId());

        Date startDate = DateUtils.getDateShort(new Date());
        Date endDate = org.apache.commons.lang3.time.DateUtils.addWeeks(startDate,orderModel.getWeeks());
        orderDetail.setStartTime(startDate);
        orderDetail.setEndTime(endDate);
        orderDetail.setPersonCount(1);
        orderDetail.setServiceId(orderInfo.getServiceId());
        orderDetail.setCourseCount(orderModel.getCourseCount());
        orderDetail.setMealCount(orderModel.getMealCount());
        orderDetail.setMealCouponCount(orderModel.getMealCount());
        orderDetail.setCashierId(userInfo.getId());
        orderDetail.setMonthCount(0);
        orderDetail.setAccountAmount(BigDecimal.ZERO);
        orderDetail.setRemark(orderModel.getRemark());
        orderDetail.setStoreId(storeId);

        orderDetailMapper.insertSelective(orderDetail);
        return orderDetail;
    }

    /**
     *@Author: timo
     *@Date: 2018/3/26 14:10
     *@Description:
     * 创建订单课程教练详情信息
     *
     *
     */
    public int createOrderCourseCoach(PresalePrivateCourseOrderModel orderModel,UserInfo userInfo , OrderInfo orderInfo){
        if(orderModel.getCoachList().size() > 0){
            List<OrderCourseCoach> orderCoachList = new ArrayList<>();
            for (CoachBriefResultModel coahcModel : orderModel.getCoachList()){
                OrderCourseCoach occ = new OrderCourseCoach();
                occ.setOrderId(orderInfo.getId());
                occ.setOrderType(orderInfo.getOrderType());
                occ.setCoachId(coahcModel.getCoachId());
                occ.setCoachName(coahcModel.getCoachName());
                String courseName = orderModel.getCourseCount()+"节"+orderModel.getCourseName()+"私教课程";
                occ.setCourseName(courseName);

                orderCoachList.add(occ);
            }
            if (orderCoachList.size() > 0){
                return orderCourseCoachMapper.insertBatch(orderCoachList);
            }
        }
        return 0;
    }

    /**
     *@Author: timo
     *@Date: 2018/3/27 00:23
     *@Description:
     * 创建私教课程信息
     *
     */
    public boolean createCourse(OrderInfo orderInfo, OrderDetail orderDetail){
        orderDetail.setMealCount(orderDetail.getMealCouponCount());
        List<OrderCourseCoach> orderCoachList = orderCourseCoachMapper.queryOrderCourseCoachByOrderId(orderInfo.getId());
        if (orderCoachList.size() > 0){

            // step 1 创建课程
            CourseInfo courseInfo = new CourseInfo();
            courseInfo.setCoachCount(orderCoachList.size());
            courseInfo.setPastCount(1);
            courseInfo.setCourseType(OrderContants.OrderType.pt.getType());
            courseInfo.setMaxCount(1);
            courseInfo.setTitle(orderCoachList.get(0).getCourseName());
            courseInfo.setCurrentCount(1);
            courseInfo.setStatus("2");
            courseInfo.setMinCount(1);
            courseInfo.setPeriods(orderDetail.getCourseCount());
            courseInfo.setIsVipUsed(0);
            courseInfo.setIsBuyOneClassLimit(1);
            courseInfo.setIsBuyOneTimeLimit(1);
            courseInfo.setMinCount(orderDetail.getCourseCount());
            courseInfo.setMaxCount(orderDetail.getCourseCount());
            int addCount = courseInfoMapper.insertSelective(courseInfo);
            if(addCount > 0){

                // step 2 创建课程教练表 coachCourse
                UserInfo openBillCoachUser = userInfoMapper.selectById(orderDetail.getCashierId());
                CoachInfo coachInfo = coachService.queryCoachByMobile(openBillCoachUser.getMobile());
                Integer storeId = storeCoachMapper.queryStoreIdByCoachId(coachInfo.getId());
                int createCoachCourseCount = createCoachCourse(courseInfo, orderCoachList, coachInfo);
                if(createCoachCourseCount > 0){
                    logger.info(" create course coach data is OK");
                }else{
                    throw new RuntimeException("create course coach data is error ");
                }

                // step 3 创建课程门店 因为教练团队只属于一个门店 所以这里只能创建一条课程门店表

                int courseStoreCount = createCourseStore(courseInfo.getId(),coachInfo,storeId);
                if(courseStoreCount > 0){
                    logger.info(" create course store data is OK");
                }else{
                    throw new RuntimeException("create course store data is error ");
                }

                // step 4 创建价格服务 servicePrice
                ServicePrice servicePrice = createServicePrice(courseInfo,orderInfo,storeId);
                if(servicePrice != null){
                    logger.info(" create course price  data is OK");
                }else{
                    throw new RuntimeException("  create course price  data is error ");
                }

                // step 5 创建日程 courseSign
                int courseSignCount = createCourseSign(courseInfo, orderInfo);
                if(courseSignCount > 0){
                    logger.info(" create course sign  data is OK");
                }else{
                    throw new RuntimeException(" create course sign  data is error");
                }

                // step 6 update orderCourseCoach
                int updateOrderCourseCoachCount = updateOrderCourseCoach(orderInfo,courseInfo,orderCoachList);
                if(updateOrderCourseCoachCount > 0){
                    logger.info(" update order course coach  data is OK");
                }else{
                    throw new RuntimeException(" update order course coach  data is error");
                }

                // step 7 update orderInfo serviceId
                orderInfo.setServiceId(servicePrice.getId());
                orderInfoMapper.updateById(orderInfo);

                return Boolean.TRUE;
            }
        }


        return Boolean.FALSE;
    }

    public ServicePrice createServicePrice(CourseInfo courseInfo, OrderInfo orderInfo, Integer storeId) {

        ServicePrice servicePrice = new ServicePrice();
        servicePrice.setCourseId(courseInfo.getId());
        servicePrice.setServiceType(Integer.valueOf(courseInfo.getCourseType()));
        servicePrice.setServiceName(courseInfo.getTitle());
        servicePrice.setPrice(orderInfo.getAmount());
        servicePrice.setPrimePrice(orderInfo.getAmount());
        servicePrice.setVersion(1);
        servicePrice.setStoreId(storeId);

        int addCount = servicePriceMapper.insert(servicePrice);

        return servicePrice;
    }

    public int createCourseSign(CourseInfo courseInfo, OrderInfo orderInfo){

        List<CourseSign> courseSignList = new ArrayList<>();
        for (Integer i = 0 ; i < courseInfo.getPeriods() ; i++){
            CourseSign courseSign = new CourseSign();
            courseSign.setCourseId(courseInfo.getId());
            courseSign.setCourseName(courseInfo.getTitle());
            courseSign.setOrderId(orderInfo.getId());
            courseSign.setCourseNumber(0);
            courseSign.setCourseSortNum(0);
            courseSign.setCoachCourseSortNum(0);
            courseSign.setPeriods(courseInfo.getPeriods());
            courseSign.setUserId(orderInfo.getUserId());
            courseSign.setIsclose("0");
            courseSign.setStatus(1);
            courseSign.setSignType(1);
            courseSign.setCourseSortNum(i+1);

            courseSignList.add(courseSign);

        }
        if(courseSignList.size() > 0){
            return courseSignMapper.insertBatch(courseSignList);
        }
        return 0;
    }

    public int createCoachCourse(CourseInfo courseInfo, List<OrderCourseCoach> coachList, CoachInfo coachInfo){
        if(coachList != null && coachList.size() > 0){
            List<CourseCoach> courseCoachList = new ArrayList<>();
            for(OrderCourseCoach occ: coachList){
                CourseCoach cc = new CourseCoach();
                cc.setCoachId(occ.getCoachId());
                cc.setCourseId(courseInfo.getId());
                cc.setStatus("1");
                if (occ.getCoachId() == coachInfo.getId())
                    cc.setIsMain("1");
                courseCoachList.add(cc);
            }

            if(courseCoachList.size() > 0){
                return courseCoachMapper.insertBatch(courseCoachList);
            }
        }
        return 0;
    }

    public int updateOrderCourseCoach(OrderInfo orderInfo, CourseInfo courseInfo, List<OrderCourseCoach> orderCourseCoachList){
        if (orderCourseCoachList != null && orderCourseCoachList.size() > 0){
            for (OrderCourseCoach occ : orderCourseCoachList){
                occ.setCourseId(courseInfo.getId());
            }
            return orderCourseCoachMapper.updateBatchById(orderCourseCoachList);
        }
        return 0;
    }

    /**
     *@Author: timo
     *@Date: 2018/4/9 11:20
     *@Description:
     * 添加课程门店
     *
     */
    public int createCourseStore(Integer courseId, CoachInfo coachInfo, Integer storeId){

        CourseStore courseStore = new CourseStore();
        courseStore.setCourseId(courseId);
        courseStore.setStoreId(storeId);
        return courseStoreMapper.insert(courseStore);
    }

    /**
     * 获取有效的交易编号
     *
     * @return
     */
    public String getTradeId() {
        Date nowDate = new Date();
        String tradeId = DateUtils.format(nowDate, DateUtils.datePatternAllSimple);
        while (true) {
            int num = (int) (Math.random() * 9000 + 1000);
            tradeId = tradeId + num;
            int bool = orderInfoMapper.checkTradeIdIsOK(tradeId);
            if (bool == 0)
                break;
        }
        return tradeId;
    }
}
